package com.llb666.java.queue;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * LinkedBlockingQueue演示
 * desc:链表阻塞队列的演示
 *  新增操作：
 *      put  首选 队列满的时候，一直阻塞
 *      add 队列满的时候抛出异常；
 *      offer 队列满的时候返回 false。会阻塞一段时间
 *
 *  查看并删除操作：
 *      take()：首选。当队列为空时阻塞
 *      remove 队列空的时候抛异常；
 *      poll 队列空的时候返回 null。
 *  只查看不删除操作：
 *      element 队列空的时候抛异常；
 *      peek 队列空的时候返回 null。
 *
 * @author liulibin
 */
public class LinkedBlockingQueueDemo {
    public static void main(String[] args) {
        try{
            BlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>(5);

            ExecutorService executor = Executors.newFixedThreadPool(5);
            Producers producer = new Producers(queue);
            for(int i=0;i<3;i++){
                executor.execute(producer);
             }
             executor.execute(new Consumer(queue));
             executor.shutdown();
             }catch (Exception e){
                 e.printStackTrace();
         }
    }

    static class Producers implements  Runnable{
        private BlockingQueue<Integer> queue;
        /**
         * 循环次数
         */
        private int nums = 5;
        /**
         * 标记数据编号
         */
        private static volatile AtomicInteger count = new AtomicInteger();
        public Producers(){}
        public Producers(BlockingQueue<Integer> queue){
            this.queue = queue;
        }
        @Override
        public void run() {
            String data = null;
            try{
                System.out.println("开始生产数据");
                System.out.println("-----------------------");
                while(nums>0){
                    nums--;
                    count.incrementAndGet();
                    Thread.sleep(500);

                    System.out.println(Thread.currentThread().getId()+ " :生产者生产了一个数据,");
                    queue.put(count.getAndIncrement());
                }
            }catch(Exception e){
                e.printStackTrace();
                Thread.currentThread().interrupt();
            }finally{
                System.out.println("生产者线程退出！");
            }
        }
    }


    static class Consumer implements Runnable{
        private BlockingQueue<Integer> queue;
        private int nums = 20;
        public Consumer(){}
        public Consumer(BlockingQueue<Integer> queue){
            this.queue = queue;
        }
        @Override
        public void run() {
            System.out.println("消费者开始消费");
            System.out.println("-------------------------");
            while(nums>0){
                nums--;
                try{
                    while(true){
                        int data = queue.take();
                        Thread.sleep(500);
                        System.out.println("消费者消费的数据是" + data);
                    }
                }catch(Exception e){
                    e.printStackTrace();
                    Thread.currentThread().interrupt();
                }finally {
                    System.out.println("消费者线程退出!");
                }
            }
        }
    }
}

